#include "../../include/session/SessionManager.hpp"
#include <sstream>
#include <random>
using namespace http::session;

std::string SessionManager::generateSessionId()
{
    std::stringstream ss;
    std::uniform_int_distribution<> dist(0, 15);//0-15的随机数
    for(int i = 0; i < 32; i++)
    {
        ss << std::hex << dist(_randomIdGenerator);
    }
    return ss.str();
}

std::string SessionManager::getSessionIdfromCookie(const HttpRequest &request)
{
    std::string session_id;
    std::string cookie = request.getHeader("Cookie");
    if(!cookie.empty())
    {
        size_t pos = cookie.find("sessionId=");
        if(pos != std::string::npos)
        {
            pos += 10;
            size_t end = cookie.find(";", pos);
            if(end == std::string::npos)
            {
                session_id = cookie.substr(pos);
            }
            else
            {
                session_id = cookie.substr(pos, end - pos);
            }
        }
    }
    return session_id;
}

void SessionManager::setSessionIdtoCookie(HttpResponse &response, const std::string &session_id)
{
    // 设置Cookie，路径为根目录，HttpOnly表示只能通过HTTP请求访问
    std::string cookie = "sessionId=" + session_id + "; Path=/; HttpOnly";
    response.addHeader("Set-Cookie", cookie);
}

SessionManager::SessionManager(std::unique_ptr<SessionStorage> session_storage)
    : _session_storage(std::move(session_storage)),
    _randomIdGenerator(std::random_device()())
{
}

std::shared_ptr<Session> SessionManager::getSession(const HttpRequest &request, HttpResponse &response)
{
    std::string session_id = getSessionIdfromCookie(request);
    std::shared_ptr<Session> session;
    // 如果session_id不为空，则从session_storage中加载session
    if(!session_id.empty())
    {
        session = _session_storage->load(session_id);
    }
    // 如果session为空或者过期，则创建一个新session
    if(!session || session->isExpired())
    {
        session_id = generateSessionId();
        session = std::make_shared<Session>(session_id,this);
        setSessionIdtoCookie(response, session_id);
    }
    // 如果session不为空，为现有会话设置管理器
    if(session)
    {
        session->SetManager(this);
    }
    session->Refresh();//刷新会话过期时间
    _session_storage->save(session);//保存会话数据
    return session;
}

void SessionManager::destroySession(const std::string &session_id)
{
    _session_storage->remove(session_id);
}

void SessionManager::updateSession(std::shared_ptr<Session> session)
{
    _session_storage->save(session);
}

void SessionManager::cleanExpiredSessions()
{
    // 注意：这个实现依赖于具体的存储实现
    // 对于内存存储，可以在加载时检查是否过期
    // 对于其他存储的实现，可能需要定期清理过期会话
}

